﻿using LD.Host;
using LD.Host.Tool;
using LD.PLC;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Web.Compilation;

namespace LD.Tool
{
    public abstract class BaseTool
    {
        /// <summary>
        /// 运行
        /// </summary>
        /// <param name="param"></param>
        public abstract OpResult Execute(TB_Tool model);

        public bool isSuccess { get; internal set; } = false;
        public string message { get; internal set; }
        public Stopwatch stopwatch { get; private set; } = new Stopwatch();
        public void Log(TB_Tool model, string msg, LogLevel level)
        {
            switch (level)
            {
                case LogLevel.一般:
                    Log4.Info($"【{model.FlowName}】【{model.Text}】{msg}");
                    break;
                case LogLevel.警告:
                    Log4.Warr($"【{model.FlowName}】【{model.Text}】{msg}");
                    break;
                case LogLevel.严重:
                    isSuccess = false;
                    Log4.Error($"【{model.FlowName}】【{model.Text}】{msg}");
                    break;
                default:
                    break;
            }
        }

        public virtual void EchoPLC(EchoPLC model1)
        {
            var _model = model1;
            //界面暂时没有写类型
            //此处固定位Int16
            _model.DataType = "Int16";
            if (_model.IsEcho)
            {
                switch (_model.DataType)
                {
                    case "Int16":
                        short val16 = 0;
                        if (short.TryParse(_model.Val, out val16))
                        {
                            var op16 = PLCFactory.Instance.Write(_model.Address, val16);
                            if (!op16.IsSuccess)
                                Log4.Warr($"写入PLC失败{_model.Address}");
                        }
                        else
                            Log4.Warr($"写入PLC数据类型错误{_model.Address}");

                        break;
                    case "Int32":
                        int val32 = 0;
                        if (int.TryParse(_model.Val, out val32))
                        {
                            var op32 = PLCFactory.Instance.Write(_model.Address, val32);
                            if (!op32.IsSuccess)
                                Log4.Warr($"写入PLC失败{_model.Address}");
                        }
                        else
                            Log4.Warr($"写入PLC数据类型错误{_model.Address}");

                        break;
                    case "Bool":
                        bool valbool = false;
                        if (bool.TryParse(_model.Val, out valbool))
                        {
                            var opbool = PLCFactory.Instance.Write(_model.Address, valbool);
                            if (!opbool.IsSuccess)
                                Log4.Warr($"写入PLC失败{_model.Address}");
                        }
                        else
                            Log4.Warr($"写入PLC数据类型错误{_model.Address}");
                        break;
                    case "Float":
                        if (float.TryParse(_model.Val, out var floatVal))
                        {
                            var opfloat = PLCFactory.Instance.Write(_model.Address, floatVal);
                            if (!opfloat.IsSuccess)
                                Log4.Warr($"写入PLC失败{_model.Address}");
                        }
                        else
                            Log4.Warr($"写入PLC数据类型错误{_model.Address}");
                        break;
                    case "String":
                        var opstring = PLCFactory.Instance.Write(_model.Address, _model.Val + "");
                        if (!opstring.IsSuccess)
                            Log4.Warr($"写入PLC失败{_model.Address}");

                        break;
                    default:
                        break;
                }
            }
        }

        public void GetFlowResultField(TB_Tool model)
        {
            //获取output字段
            var propers = this.GetType().GetProperties();
            bool flag = false;
            foreach (var item in propers)
            {
                ToolAttribute toolAttribute1 = (ToolAttribute)item.GetCustomAttribute(typeof(ToolAttribute), true);
                if (toolAttribute1 != null && toolAttribute1.Output)
                {

                    var flow = Appbus.PartNo.Config.Flow.Where(p => p.Name == model.FlowName).FirstOrDefault();
                    if (flow == null)
                        return;
                    var tool = flow.Tools.Where(p => p.Name == model.Name).FirstOrDefault();
                    if (tool == null)
                        return;
                    if (tool.OutPut == null)
                        tool.OutPut = new Dictionary<string, object>();
                    if (!flag)
                    {
                        tool.OutPut.Clear();
                        flag = true;
                    }
                    tool.OutPut.Add(item.Name, item.GetValue(this));
                }
            }
        }
        public object GetToolValue(TB_Tool model, string flowPath)
        {
            if (flowPath == null) return null;
            string[] node = flowPath.Split('\\');
            var flow = Appbus.PartNo.Config.Flow.Where(p => p.Name == model.FlowName).FirstOrDefault();
            if (flow != null)
            {
                var tool = flow.Tools.Where(p => p.Name == node[0]).FirstOrDefault();
                if (tool.OutPut == null)
                    return null;
                if (!tool.OutPut.ContainsKey(node[1]))
                    return null;
                return tool.OutPut[node[1]];
            }
            return null;
        }
    }
}
